package cn.edu.sgu.www.mhxysy.service.repository.impl;

import cn.edu.sgu.www.mhxysy.consts.CustomMessages;
import cn.edu.sgu.www.mhxysy.consts.IdentifierPrefixes;
import cn.edu.sgu.www.mhxysy.dto.repository.RoleRepositoryDTO;
import cn.edu.sgu.www.mhxysy.entity.repository.RepositoryGrid;
import cn.edu.sgu.www.mhxysy.entity.repository.RepositoryProp;
import cn.edu.sgu.www.mhxysy.entity.repository.RoleRepository;
import cn.edu.sgu.www.mhxysy.mapper.repository.RepositoryGridMapper;
import cn.edu.sgu.www.mhxysy.mapper.repository.RepositoryPropMapper;
import cn.edu.sgu.www.mhxysy.mapper.repository.RoleRepositoryMapper;
import cn.edu.sgu.www.mhxysy.pager.Pager;
import cn.edu.sgu.www.mhxysy.pager.repository.RoleRepositoryPager;
import cn.edu.sgu.www.mhxysy.redis.RedisUtils;
import cn.edu.sgu.www.mhxysy.service.repository.RoleRepositoryService;
import cn.edu.sgu.www.mhxysy.util.ObjectUtils;
import cn.edu.sgu.www.mhxysy.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author 沐雨橙风ιε
 * @version 1.0
 */
@Service
public class RoleRepositoryServiceImpl implements RoleRepositoryService {

    private final RedisUtils redisUtils;
    private final RoleRepositoryMapper roleRepositoryMapper;
    private final RepositoryGridMapper repositoryGridMapper;
    private final RepositoryPropMapper repositoryPropMapper;

    @Autowired
    public RoleRepositoryServiceImpl(
            RedisUtils redisUtils,
            RoleRepositoryMapper roleRepositoryMapper,
            RepositoryGridMapper repositoryGridMapper,
            RepositoryPropMapper repositoryPropMapper) {
        this.redisUtils = redisUtils;
        this.roleRepositoryMapper = roleRepositoryMapper;
        this.repositoryGridMapper = repositoryGridMapper;
        this.repositoryPropMapper = repositoryPropMapper;
    }

    @Override
    public void init(String roleId, Integer count) {
        // 查询角色包裹
        Map<String, Object> columnMap = new HashMap<>();

        columnMap.put("role_id", roleId);

        List<RoleRepository> roleRepositories = roleRepositoryMapper.selectByMap(columnMap);

        if (roleRepositories.size() > 0) {
            // 删除角色仓库
            roleRepositoryMapper.deleteByMap(columnMap);
        }

        Map<Integer, String> nameMap = new HashMap<>();

        for (RoleRepository roleRepository : roleRepositories) {
            nameMap.put(roleRepository.getLocation(), roleRepository.getName());
        }

        for (int location = 1; location <= count; location++) {
            /*
             * 添加仓库
             */
            RoleRepository roleRepository = new RoleRepository();

            roleRepository.setId(IdentifierPrefixes.PREFIX_JSCK + redisUtils.uuid());
            roleRepository.setLocation(location);
            roleRepository.setRoleId(roleId);

            if (nameMap.containsKey(location)) {
                roleRepository.setName(nameMap.get(location));
            } else {
                roleRepository.setName("仓库" + location);
            }

            roleRepositoryMapper.insert(roleRepository);

            /*
             * 批量添加仓库格子
             */
            List<RepositoryGrid> list = new ArrayList<>();

            for (int i = 1; i <= 25; i++) {
                RepositoryGrid repositoryGrid = new RepositoryGrid();

                repositoryGrid.setRepositoryId(roleRepository.getId());
                repositoryGrid.setLocation(i);
                repositoryGrid.setId(IdentifierPrefixes.PREFIX_CKGZ + redisUtils.uuid());

                list.add(repositoryGrid);
            }

            repositoryGridMapper.insertList(list);
        }
    }

    @Override
    public void unlock(String roleId) {
        /*
         * 添加仓库
         */
        QueryWrapper<RoleRepository> queryWrapper = new QueryWrapper<>();

        queryWrapper.eq(
                StringUtils.isNotEmpty(roleId),
                "role_id", roleId
        );

        Long count = roleRepositoryMapper.selectCount(queryWrapper);

        int loaction = (int) (count + 1);

        RoleRepository repository = new RoleRepository();

        repository.setId(repository.uuid());
        repository.setName("仓库" + loaction);
        repository.setRoleId(roleId);
        repository.setLocation(loaction);

        roleRepositoryMapper.insert(repository);

        /*
         * 添加仓库格子
         */
        String repositoryId = repository.getId();

        for (int i = 1; i <= 25; i++) {
            RepositoryGrid repositoryGrid = new RepositoryGrid();

            repositoryGrid.setId(IdentifierPrefixes.PREFIX_CKGZ + redisUtils.uuid());
            repositoryGrid.setLocation(i);
            repositoryGrid.setRepositoryId(repositoryId);

            repositoryGridMapper.insert(repositoryGrid);
        }
    }

    @Override
    public void insert(RoleRepositoryDTO repositoryDTO) {
        // 1、添加仓库
        RoleRepository repository = toEntity(repositoryDTO);

        repository.setId(repository.uuid());

        roleRepositoryMapper.insert(repository);

        // 2、添加仓库格子
        String repositoryId = repository.getId();

        for (int i = 1; i <= 25; i++) {
            RepositoryGrid repositoryGrid = new RepositoryGrid();

            repositoryGrid.setId(IdentifierPrefixes.PREFIX_CKGZ + redisUtils.uuid());
            repositoryGrid.setLocation(i);
            repositoryGrid.setRepositoryId(repositoryId);

            repositoryGridMapper.insert(repositoryGrid);
        }
    }

    @Override
    public void deleteById(String repositoryId) {
        // 查询仓库的全部格子
        Map<String, Object> map = new HashMap<>();

        map.put("repository_id", repositoryId);

        List<RepositoryGrid> list = repositoryGridMapper.selectByMap(map);

        // 获取所有仓库格子ID
        Stream<RepositoryGrid> stream = list.stream();

        List<String> ids = stream.map(new Function<RepositoryGrid, String>() {
            @Override
            public String apply(RepositoryGrid repositoryGrid) {
                return repositoryGrid.getId();
            }
        }).collect(Collectors.toList());

        // 1、删除仓库物品
        QueryWrapper<RepositoryProp> queryWrapper = new QueryWrapper<>();

        queryWrapper.in("grid_id", ids);

        repositoryPropMapper.delete(queryWrapper);

        // 2、删除仓库的格子
        UpdateWrapper<RepositoryGrid> updateWrapper = new UpdateWrapper<>();

        updateWrapper.eq("repository_id", repositoryId);

        repositoryGridMapper.delete(updateWrapper);

        // 3、删除仓库
        roleRepositoryMapper.deleteById(repositoryId);
    }

    @Override
    public void updateById(RoleRepositoryDTO repositoryDTO) {
        ObjectUtils.requireNonNull(repositoryDTO.getId(), CustomMessages.ID_NOT_NULL);

        RoleRepository repository = toEntity(repositoryDTO);

        roleRepositoryMapper.updateById(repository);
    }

    @Override
    public void updateNameById(String id, String name) {
        UpdateWrapper<RoleRepository> updateWrapper = new UpdateWrapper<>();

        updateWrapper.eq("id", id);
        updateWrapper.set("name", name);

        roleRepositoryMapper.update(updateWrapper.getEntity(), updateWrapper);
    }

    @Override
    public List<RoleRepository> selectByRoleId(String roleId) {
        if (StringUtils.isNullOrEmpty(roleId)) {
            return new ArrayList<>();
        }

        QueryWrapper<RoleRepository> queryWrapper = new QueryWrapper<>();

        queryWrapper.eq("role_id", roleId);

        return roleRepositoryMapper.selectList(queryWrapper);
    }

    @Override
    public Page<RoleRepository> selectByPage(RoleRepositoryPager pager) {
        QueryWrapper<RoleRepository> queryWrapper = new QueryWrapper<>();
        Page<RoleRepository> page = Pager.ofPage(pager);

        queryWrapper.eq(
                StringUtils.isNotEmpty(pager.getRoleId()),
                "role_id", pager.getRoleId()
        );

        return roleRepositoryMapper.selectPage(page, queryWrapper);
    }

    private RoleRepository toEntity(RoleRepositoryDTO repositoryDTO) {
        RoleRepository repository = new RoleRepository();

        repository.setId(repositoryDTO.getId());
        repository.setName(repositoryDTO.getName());
        repository.setRoleId(repositoryDTO.getRoleId());
        repository.setLocation(repositoryDTO.getLocation());

        return repository;
    }

}